"""
股票 API 路由
"""
import logging
from typing import List, Optional
from fastapi import APIRouter, HTTPException, Depends, Query
from sqlalchemy.orm import Session
from datetime import datetime, date

from database import get_db, TradingSignal
from api.stock_api import StockAPIClient
from analysis.signal_generator import SignalGenerator
from schemas import StockResponse, StockHistoryResponse, TradingSignalResponse, StockAnalysisResponse
from config import config

logger = logging.getLogger(__name__)

router = APIRouter()
stock_api = StockAPIClient()
signal_generator = SignalGenerator()

# 股票代码到名称的映射（用于离线模式）
STOCK_NAME_MAP = {
    # 白酒板块
    '600519': '贵州茅台',
    '000858': '五粮液',
    '600809': '山西汾酒',
    '000596': '古井贡酒',
    '600779': '水井坊',
    '000568': '泸州老窖',
    '000799': '酒鬼酒',
    '600132': '重庆啤酒',
    '600197': '伊力特',
    '000869': '张裕A',
    '600559': '老白干酒',
    '600600': '青岛啤酒',
    '000729': '燕京啤酒',
    
    # 银行板块
    '600036': '招商银行',
    '601166': '兴业银行',
    '600000': '浦发银行',
    '000001': '平安银行',
    '601398': '工商银行',
    '601939': '建设银行',
    '601288': '农业银行',
    '601988': '中国银行',
    '601328': '交通银行',
    '002142': '宁波银行',
    
    # 新能源板块
    '002594': '比亚迪',
    '300750': '宁德时代',
    '002460': '赣锋锂业',
    '300274': '阳光电源',
    '688599': '天合光能',
    '002466': '天齐锂业',
    '300438': '鹏辉能源',
    '002812': '恩捷股份',
    '300450': '先导智能',
    '300073': '当升科技',
    '300037': '新宙邦',
    '002709': '天赐材料',
    '300068': '南都电源',
    '300316': '晶盛机电',
    '300751': '迈为股份',
    '300118': '东方日升',
    '002074': '国轩高科',
    '002202': '金风科技',
    '688005': '容百科技',
    '002459': '晶澳科技',
    '601012': '隆基绿能',
    
    # 科技板块
    '603259': '药明康德',
    '300760': '迈瑞医疗',
    '688981': '中芯国际',
    '002415': '海康威视',
    '000725': '京东方A',
    '002230': '科大讯飞',
    '300059': '东方财富',
    '002475': '立讯精密',
    '000066': '中国长城',
    '002027': '分众传媒',
    '300433': '蓝思科技',
    '002241': '歌尔股份',
    '000100': 'TCL科技',
    '002352': '顺丰控股',
    '300014': '亿纬锂能',
    '002050': '三花智控',
    '688036': '传音控股',
    '300124': '汇川技术',
    '002120': '韵达股份',
    
    # 消费板块
    '000651': '格力电器',
    '000333': '美的集团',
    '601888': '中国中免',
    '600276': '恒瑞医药',
    '600887': '伊利股份',
    '600690': '海尔智家',
    '600298': '安琪酵母',
    '000895': '双汇发展',
    '603288': '海天味业',
    '002557': '洽洽食品',
    '000716': '黑芝麻',
    '002847': '盐津铺子',
    '300498': '温氏股份',
    '000876': '新希望',
    '002311': '海大集团',
    '002216': '三全食品',
    '000019': '深深宝A',
    '600300': '维维股份',
    
    # 金融保险板块
    '601318': '中国平安',
    '600030': '中信证券',
    '601601': '中国太保',
    '601336': '新华保险',
    '601319': '中国人保',
    '000783': '长江证券',
    '002736': '国信证券',
    '600837': '海通证券',
    '000166': '申万宏源',
    '601066': '中信建投',
    '002797': '第一创业',
    '600958': '东方证券',
    '000750': '国海证券',
    '002926': '华西证券',
    '600999': '招商证券',
    '600061': '国投资本',
    '000686': '东北证券',
    '600621': '华鑫股份',
    '601788': '光大证券',
    '002500': '山西证券',
    '000728': '国元证券',
    '600369': '西南证券',
    
    # 房地产板块
    '000002': '万科A',
    '600048': '保利发展',
    '001979': '招商蛇口',
    '000069': '华侨城A',
    '600383': '金地集团',
    '600340': '华夏幸福',
    '000656': '金科股份',
    '000718': '苏宁环球',
    '600266': '北京城建',
    '600895': '张江高科',
    '000402': '金融街',
    '600663': '陆家嘴',
    '000031': '中粮地产',
    '600240': '华业资本',
    '000517': '荣安地产',
    '000540': '中天金融',
    '000732': '泰禾集团',
    '000043': '中航地产',
    '600503': '华丽家族',
    '000036': '华联控股',
    
    # 电力公用事业
    '600886': '国投电力',
    '600795': '国电电力',
    '000027': '深圳能源',
    '600021': '上海电力',
    '600011': '华能国际',
    '000883': '湖北能源',
    '600674': '川投能源',
    '000899': '赣能股份',
    '600900': '长江电力',
    '000966': '长源电力',
    '000875': '吉电股份',
    '600744': '华银电力',
    '600236': '桂冠电力',
    '000531': '穗恒运A',
    '600726': '华电能源',
    '600023': '浙能电力',
    '000600': '建投能源',
    '000767': '漳泽电力',
    '600863': '内蒙华电',
    '000692': '惠天热电',
    
    # 基建建材股
    '601390': '中国中铁',
    '000425': '徐工机械',
    '000157': '中联重科',
    '002152': '广电运通',
    '600170': '上海建工',
    '600068': '葛洲坝',
    '000401': '冀东水泥',
    '600801': '华新水泥',
    '002233': '塔牌集团',
    '000877': '天山股份',
    '600217': '中再资环',
    '600761': '安徽合力',
    '002271': '东方雨虹',
    '000786': '北新建材',
    '600309': '万华化学',
    '000792': '盐湖股份',
    '600426': '华鲁恒升',
    '600989': '宝丰能源',
    '002648': '卫星石化',
    '000059': '华锦股份',
    
    # 医药生物股
    '000538': '云南白药',
    '600436': '片仔癀',
    '002821': '凯莱英',
    '300347': '泰格医药',
    '002001': '新和成',
    '300122': '智飞生物',
    '600161': '天坛生物',
    '300601': '康泰生物',
    '000661': '长春高新',
    '002007': '华兰生物',
    '603392': '万泰生物',
    '688185': '康希诺',
    '600867': '通化东宝',
    '002422': '科伦药业',
    '002038': '双鹭药业',
    '300558': '贝达药业',
    '300529': '健帆生物',
    '002030': '达安基因',
    '300003': '乐普医疗',
    '002462': '嘉事堂',
    '300015': '爱尔眼科',
}

def get_stock_name(symbol: str) -> str:
    """获取股票名称"""
    return STOCK_NAME_MAP.get(symbol, f'股票{symbol}')

@router.get("/stocks/popular", response_model=List[StockResponse])
async def get_popular_stocks(db: Session = Depends(get_db)):
    """
    获取热门股票列表
    """
    try:
        logger.info("📈 获取热门股票列表")
        stocks = stock_api.get_realtime_data(config.POPULAR_STOCKS)
        
        if not stocks:
            raise HTTPException(status_code=500, detail="无法获取股票数据")
        
        return stocks
    except Exception as e:
        logger.error(f"❌ 获取热门股票失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/stocks/recommended/buy", response_model=List[StockResponse], response_model_by_alias=True)
async def get_recommended_buy_stocks(db: Session = Depends(get_db)):
    """
    获取首页推荐买入的10只股票（从数据库获取最新推荐）
    App首页打开时主动调用此API - 优化版本，快速响应
    """
    try:
        logger.info("💰 获取首页推荐买入股票列表（最新10只）- 快速模式")
        
        # 1. 快速查询最新的买入信号（优化查询性能）
        today = date.today()
        
        # 使用更快的查询方式，避免在定时任务运行时阻塞
        buy_signals = db.query(TradingSignal).filter(
            TradingSignal.signal_date == today,
            TradingSignal.signal_type.in_(['BUY', 'STRONG_BUY'])
        ).order_by(
            TradingSignal.strength.desc(),      # 优先按信号强度排序
            TradingSignal.created_at.desc()     # 然后按创建时间排序
        ).limit(10).all()  # 限制返回10只股票
        
        if not buy_signals:
            logger.info("📭 今天暂无买入推荐")
            return []
        
        logger.info(f"📊 找到 {len(buy_signals)} 个高质量买入推荐")
        
        # 2. 直接使用数据库信号数据创建响应（简化流程，提高性能）
        enhanced_stocks = []
        for signal in buy_signals:
            symbol = signal.symbol.replace('sh', '').replace('sz', '')
            stock_data = {
                'symbol': symbol,
                'name': get_stock_name(symbol),
                'currentPrice': signal.price or 0.0,
                'change': 0.0,  # 首页不需要实时涨跌数据
                'changePercent': 0.0,
                'volume': 0,  # 必需字段
                'sector': '蓝筹股',
                'marketCap': None,  # 可选字段
                'signalType': signal.signal_type,
                'signalStrength': signal.strength,
                'buyPrice': signal.action_price or signal.price or 0.0,
                'targetPrice': signal.target_price,
                'stopLoss': signal.stop_loss,
                'signalReason': signal.reason or '技术分析推荐',
                'signalDate': signal.signal_date.strftime('%Y-%m-%d') if signal.signal_date else None
            }
            enhanced_stocks.append(stock_data)
            logger.debug(f"  ✅ {symbol}: {signal.signal_type} (强度:{signal.strength}) - {signal.reason[:30]}...")
        
        logger.info(f"✅ 返回 {len(enhanced_stocks)} 个首页推荐买入股票")
        return enhanced_stocks
        
    except Exception as e:
        logger.error(f"❌ 获取推荐买入股票失败: {e}")
        import traceback
        logger.error(traceback.format_exc())
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/scheduler/status")
async def get_scheduler_status():
    """获取异步调度器状态"""
    try:
        from async_scheduler import async_scheduler
        status = async_scheduler.get_status()
        return {
            "scheduler_status": status,
            "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }
    except Exception as e:
        logger.error(f"❌ 获取调度器状态失败: {e}")
        return {"error": str(e)}

@router.post("/scheduler/trigger")
async def trigger_analysis():
    """手动触发股票分析"""
    try:
        from async_scheduler import async_scheduler
        success = async_scheduler.trigger_analysis()
        if success:
            return {
                "message": "分析任务已添加到队列",
                "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
        else:
            return {"error": "调度器未运行"}
    except Exception as e:
        logger.error(f"❌ 触发分析失败: {e}")
        return {"error": str(e)}

@router.get("/stocks/{symbol}", response_model=StockResponse)
async def get_stock_detail(symbol: str, db: Session = Depends(get_db)):
    """
    获取股票详情（包含交易信号）
    """
    try:
        logger.info(f"📊 获取股票详情: {symbol}")
        
        # 处理可能的前缀（sh/sz）
        clean_symbol = symbol.replace('sh', '').replace('sz', '')
        
        # 1. 获取实时股票数据
        stocks = stock_api.get_realtime_data([clean_symbol])
        
        if not stocks:
            raise HTTPException(status_code=404, detail="股票不存在")
        
        stock_data = stocks[0]
        
        # 2. 查询交易信号
        today = date.today()
        signal = db.query(TradingSignal).filter(
            TradingSignal.symbol.in_([clean_symbol, f'sh{clean_symbol}', f'sz{clean_symbol}']),
            TradingSignal.signal_date == today
        ).order_by(TradingSignal.created_at.desc()).first()
        
        # 3. 构建完整的响应数据
        response_data = {
            'symbol': clean_symbol,
            'name': stock_data.get('name', get_stock_name(clean_symbol)),
            'currentPrice': stock_data.get('current_price', 0.0),
            'change': stock_data.get('change', 0.0),
            'changePercent': stock_data.get('change_percent', 0.0),
            'volume': stock_data.get('volume', 0),
            'sector': stock_data.get('sector') or '蓝筹股',
            'marketCap': None,  # 可选字段
        }
        
        # 4. 添加交易信号信息（如果有）
        if signal:
            response_data.update({
                'signalType': signal.signal_type,
                'signalStrength': signal.strength,
                'buyPrice': signal.action_price or signal.price,
                'targetPrice': signal.target_price,
                'stopLoss': signal.stop_loss,
                'signalReason': signal.reason or '技术分析推荐',
                'signalDate': signal.signal_date.strftime('%Y-%m-%d') if signal.signal_date else None
            })
        
        logger.info(f"✅ 股票详情获取成功: {clean_symbol} - {response_data['name']}")
        return response_data
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ 获取股票详情失败: {e}")
        import traceback
        logger.error(traceback.format_exc())
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/stocks/{symbol}/history", response_model=List[StockHistoryResponse])
async def get_stock_history(
    symbol: str, 
    days: int = Query(default=90, ge=1, le=365),
    db: Session = Depends(get_db)
):
    """
    获取股票历史K线数据（仅真实数据）
    """
    try:
        logger.info(f"📊 获取历史数据: {symbol}, 天数: {days}")
        history = stock_api.get_history_data(symbol, days)
        
        if not history:
            raise HTTPException(status_code=503, detail="所有数据源均不可用，请稍后重试")
        
        return history
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ 获取历史数据失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/stocks/{symbol}/signal", response_model=TradingSignalResponse)
async def get_trading_signal(symbol: str, db: Session = Depends(get_db)):
    """
    获取交易信号（优先返回当天已保存的信号，没有则实时生成）
    """
    try:
        logger.info(f"🎯 获取交易信号: {symbol}")
        
        # 处理可能的前缀（sh/sz）
        clean_symbol = symbol.replace('sh', '').replace('sz', '')
        
        # 1. 优先查询数据库中今天的信号
        today = date.today()
        saved_signals = db.query(TradingSignal).filter(
            TradingSignal.symbol.in_([symbol, f'sh{clean_symbol}', f'sz{clean_symbol}']),
            TradingSignal.signal_date == today
        ).order_by(TradingSignal.created_at.desc()).all()
        
        if saved_signals:
            # 找到今天的信号，直接返回
            latest_signal = saved_signals[0]
            logger.info(f"✅ 找到数据库中的信号: {latest_signal.signal_type} (强度: {latest_signal.strength})")
            
            # 解析indicators JSON字符串为字典
            import json
            try:
                indicators_dict = json.loads(latest_signal.indicators) if latest_signal.indicators else {}
            except (json.JSONDecodeError, TypeError):
                indicators_dict = {}
            
            return TradingSignalResponse(
                symbol=clean_symbol,
                signal_type=latest_signal.signal_type,
                strength=latest_signal.strength,
                price=latest_signal.price,
                action_price=latest_signal.action_price,  # 建议买入/卖出价格
                target_price=latest_signal.target_price,
                stop_loss=latest_signal.stop_loss,
                reason=latest_signal.reason,
                indicators=indicators_dict,
                action_time=latest_signal.signal_date.strftime('%Y-%m-%d') if latest_signal.signal_date else None
            )
        
        # 2. 数据库没有，实时生成信号
        logger.info(f"💡 数据库无今日信号，实时生成...")
        
        # 2.1 获取历史数据用于技术分析（90天，显示到当天）
        history = stock_api.get_history_data(clean_symbol, 90)
        
        if not history:
            raise HTTPException(status_code=503, detail="无法获取历史数据，所有数据源均不可用")
        
        # 2.2 获取实时价格
        realtime_data = stock_api.get_realtime_data([clean_symbol])
        if realtime_data:
            realtime_price = realtime_data[0]['current_price']
            logger.info(f"💰 实时价格: ¥{realtime_price}")
            
            # 将实时价格添加到历史数据末尾用于信号生成
            import time
            current_time = int(time.time() * 1000)
            realtime_bar = {
                'timestamp': current_time,
                'close': realtime_price,
                'open': realtime_price,
                'high': realtime_price,
                'low': realtime_price,
                'volume': 0
            }
            # 替换最后一个K线为实时数据
            history[-1] = realtime_bar
        else:
            logger.warning(f"⚠️ 无法获取实时价格，使用历史收盘价")
        
        # 2.3 生成信号
        signal = signal_generator.generate_signal(clean_symbol, history)
        
        if not signal:
            raise HTTPException(status_code=500, detail="无法生成交易信号")
        
        logger.info(f"✅ 实时生成信号: {signal['signal_type']} (强度: {signal['strength']})")
        
        # 解析indicators JSON字符串为字典
        import json
        try:
            indicators_dict = json.loads(signal['indicators']) if signal.get('indicators') else {}
        except (json.JSONDecodeError, TypeError):
            indicators_dict = {}
        
        return TradingSignalResponse(
            symbol=clean_symbol,
            signal_type=signal['signal_type'],
            strength=signal['strength'],
            price=signal['price'],
            action_price=signal.get('action_price'),
            target_price=signal.get('target_price'),
            stop_loss=signal.get('stop_loss'),
            reason=signal['reason'],
            indicators=indicators_dict,
            action_time=signal.get('action_time')
        )
        
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ 获取交易信号失败: {e}")
        import traceback
        logger.error(traceback.format_exc())
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/stocks/{symbol}/trading-points")
async def get_trading_points(symbol: str, db: Session = Depends(get_db)):
    """
    获取历史买卖点（仅真实数据）
    """
    try:
        logger.info(f"📍 识别买卖点: {symbol}")
        
        # 获取历史数据（90天，显示到当天）
        history = stock_api.get_history_data(symbol, 90)
        
        if not history:
            raise HTTPException(status_code=503, detail="无法获取历史数据，所有数据源均不可用")
        
        # 识别买卖点
        trading_points = signal_generator.identify_trading_points(history)
        
        return trading_points
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"❌ 识别买卖点失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/stocks/search", response_model=List[StockResponse])
async def search_stocks(
    q: str = Query(..., min_length=1),
    db: Session = Depends(get_db)
):
    """
    搜索股票
    """
    try:
        logger.info(f"🔍 搜索股票: {q}")
        
        # 从热门股票中搜索
        all_stocks = stock_api.get_realtime_data(config.POPULAR_STOCKS)
        
        results = [
            stock for stock in all_stocks
            if q.lower() in stock['symbol'].lower() or q.lower() in stock['name'].lower()
        ]
        
        return results
    except Exception as e:
        logger.error(f"❌ 搜索股票失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

@router.get("/analysis/batch", response_model=List[StockAnalysisResponse])
async def analyze_batch_stocks(db: Session = Depends(get_db)):
    """
    批量分析股票，预测买卖点
    """
    try:
        logger.info("📊 批量分析股票")
        
        # 获取所有热门股票
        stocks = stock_api.get_realtime_data(config.POPULAR_STOCKS)
        analysis_list = []
        
        for stock in stocks:
            try:
                symbol = stock['symbol']
                
                # 获取历史数据（90天，显示到当天）
                history = stock_api.get_history_data(symbol, 90)
                if not history:
                    logger.warning(f"⚠️ 跳过 {symbol}，无法获取历史数据")
                    continue
                
                # 生成交易信号
                signal = signal_generator.generate_signal(symbol, history)
                
                # 识别买卖点
                trading_points = signal_generator.identify_trading_points(history)
                buy_points = [p for p in trading_points if p['type'] == 'BUY']
                sell_points = [p for p in trading_points if p['type'] == 'SELL']
                
                # 最新操作建议
                latest_action = "持有观望"
                if signal:
                    action_map = {
                        "STRONG_BUY": "强烈买入",
                        "BUY": "买入",
                        "SELL": "卖出",
                        "STRONG_SELL": "强烈卖出",
                        "HOLD": "持有观望"
                    }
                    latest_action = action_map.get(signal['signal_type'], "持有观望")
                
                analysis_list.append({
                    "symbol": stock['symbol'],
                    "name": stock['name'],
                    "industry": stock.get('sector', ''),
                    "current_price": stock['current_price'],
                    "trading_signal": signal,
                    "buy_points": buy_points,
                    "sell_points": sell_points,
                    "latest_action": latest_action,
                    "action_time": signal['action_time'] if signal else None
                })
                
            except Exception as e:
                logger.error(f"分析股票 {stock['symbol']} 失败: {e}")
                continue
        
        # 按信号强度排序
        analysis_list.sort(
            key=lambda x: x['trading_signal']['strength'] if x['trading_signal'] else 0,
            reverse=True
        )
        
        return analysis_list
        
    except Exception as e:
        logger.error(f"❌ 批量分析失败: {e}")
        raise HTTPException(status_code=500, detail=str(e))

def generate_mock_history(symbol: str, days: int) -> List[dict]:
    """生成模拟历史数据（降级方案）"""
    import random
    from datetime import datetime, timedelta
    
    # 基础价格
    base_prices = {
        "600519": 1650.0,
        "000858": 175.0,
        "601318": 45.0,
        "600036": 45.0,
        "000651": 35.0,
        "002594": 280.0,
        "600809": 265.0,
        "300750": 170.0,
        "603259": 70.0,
        "601888": 95.0,
    }
    
    base_price = base_prices.get(symbol, 50.0)
    prices = []
    
    start_date = datetime(2025, 9, 1)
    
    for i in range(days):
        date = start_date + timedelta(days=i)
        timestamp = int(date.timestamp() * 1000)
        
        change = random.uniform(-0.03, 0.03)
        base_price *= (1 + change)
        
        open_price = base_price * (1 + random.uniform(-0.01, 0.01))
        close_price = base_price * (1 + random.uniform(-0.01, 0.01))
        high = max(open_price, close_price) * (1 + random.uniform(0.01, 0.03))
        low = min(open_price, close_price) * (1 - random.uniform(0.01, 0.03))
        volume = random.randint(50000000, 150000000)
        
        prices.append({
            "timestamp": timestamp,
            "open": round(open_price, 2),
            "high": round(high, 2),
            "low": round(low, 2),
            "close": round(close_price, 2),
            "volume": volume
        })
    
    return prices

